
#if	!defined( __20080831_DEF_LINUX_DIRITERATOR_H__ )
#define	__20080831_DEF_LINUX_DIRITERATOR_H__

#if	defined( PCE_CFG_OS_Linux )

//#include	<sys/types.h>
#include	<dirent.h>
//#include	<unistd.h>
#include	<errno.h>
#include	<stdio.h>
#include	<string>

namespace PCE_Lib {
namespace CEnv_Def {
namespace PCE_Lib_CurrentCEnvironment {
namespace Tools {

class DirIterator
{
public:
	class DirEntry
	{
	public:
		void Clear( void ) throw() { m_Path.clear(); m_Name.clear(); }
	public:
		DirEntry( void ) throw() : m_Path(), m_Name() {}
	public:
		::std::string	m_Path;
		::std::string	m_Name;
	};
public:
	const DirEntry * Read( void ) throw()
	{
		assert( NotNull( m_Dir ) );

		struct dirent	* pDir = readdir( m_Dir );
		if( IsNull( pDir ) ) {
			return Null< const DirEntry * >();
		}
		m_Entry.m_Name = pDir->d_name;
		return & m_Entry;
	}
	bool Open( const char_t * dir )
	{
		assert( NotNull( dir ) );

		if( ! Close() ) {
			return false;
		}
		m_Entry.m_Path = dir;
		if( (m_Entry.m_Path.size() > 0) && ('/' != *(m_Entry.m_Path.end() - 1)) ) {
			m_Entry.m_Path += '/';
		}

		m_Dir = opendir( dir );
		return NotNull( m_Dir );
	}
	bool Close( void ) throw()
	{
		bool	ret_val = true;
		m_Entry.Clear();
		if( NotNull( m_Dir ) ) {
			ret_val = ( 0 == closedir( m_Dir ) );
			SetNull( m_Dir );
		}
		return ret_val;
	}
public:
	DirIterator( void ) throw() : m_Entry(), m_Dir() {}
	~DirIterator( void ) throw() { Close(); }
protected:
	DirEntry	m_Entry;
	DIR			* m_Dir;
};

}	// Tools
}	// PCE_Lib_CurrentCEnvironment
}	// CEnv_Def
}	// PCE_Lib

#else
	#error DirIterator_Linux.h can only be used on Linux platform!
#endif	// PCE_CFG_OS_Linux

#endif	// __20080831_DEF_LINUX_DIRITERATOR_H__
